<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
	<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
	<TITLE></TITLE>
	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.0  (Linux)">
	<META NAME="CREATED" CONTENT="20030630;21474000">
	<META NAME="CHANGED" CONTENT="20031122;22572000">
	<STYLE>
	<!--
		@page { size: 8.5in 11in; margin-left: 1.25in; margin-right: 1.25in; margin-top: 1in; margin-bottom: 1in }
		TD P { margin-bottom: 0.08in }
		P { margin-bottom: 0.08in }
	-->
	</STYLE>
</HEAD>
<BODY LANG="en-US" DIR="LTR">
<P ALIGN=CENTER STYLE="margin-bottom: 0in"><FONT SIZE=4><B>Developing
a Spring Framework MVC application step-by-step</B></FONT></P>
<P ALIGN=CENTER STYLE="margin-bottom: 0in">Part 4 – Implementing
Database Persistence</P>
<P ALIGN=CENTER STYLE="margin-bottom: 0in"><B>Thomas Risberg</B>
<BR>August, 2003</P>
<P ALIGN=CENTER STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in">This is Part 4 of a step-by-step
account of how to develop a web application from scratch using the
Spring Framework. In Part 1 (Steps 1 – 12) we configured the
environment and set up a basic application that we will build upon.
Part 2 (Steps 13-18) improved the application in several ways. Part 3
(Steps 19-22) Added some unit tests to the application and we also
added a Form for performing a price increase. In Part 4 it is time to
deal with database persistence. We saw in the earlier parts how we
loaded some business objects using bean definitions in a
configuration file. It is obvious that this would never work in real
life – whenever we re-start the server we are back to the original
prices. We need to add code to actually persist these changes to a
database.</P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><B>Step 23 – Add Ant tasks to create
and load test data</B></P>
<P STYLE="margin-bottom: 0in">Before we can start developing the
persistence code, we should create the database tables that we need
for our development and testing. We also need a database. I am
planning on using HSQL, which is a good open source database written
in Java. This database is distributed with Spring's Petclinic sample
application, so we can just copy the jar file to the web apps lib
directory. Copy
spring-framework-1.0/samples/petclinic/war/WEB-INF/lib/hsqldb.jar
to springapp/war/WEB-INF/lib/. I am planning on using HSQL in a
standalone mode to begin with. That way we don't have to worry about
starting up a separate database server every time we use it. The URL
we specify for connecting to HSQL controls the mode that the database
is running in. To be able to run some Ant tasks for the database we
have to add some database properties to the build properties file.</P>
<TABLE WIDTH=90% BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0>
	<COL WIDTH=256*>
	<TR>
		<TD WIDTH=100% VALIGN=TOP BGCOLOR="#ffcc99">
			<P><B><FONT SIZE=2><FONT FACE="Nimbus Mono L">springapp/build.properties</FONT></FONT></B>
						</P>
		</TD>
	</TR>
	<TR>
		<TD WIDTH=100% VALIGN=TOP BGCOLOR="#ffffcc">
			<PRE># Ant properties for building the springapp

deploy.path=/home/trisberg/jakarta-tomcat-4.1.24/webapps
#deploy.path=c:/Tomcat 4.1/webapps
#deploy.path=c:/bea/user_projects/domains/mydomain/applications

tomcat.home=/home/trisberg/jakarta-tomcat-4.1.24
#tomcat.home= c:/Tomcat 4.1
tomcat.manager.url=http://localhost:8080/manager
tomcat.manager.username=admin
tomcat.manager.password=tomcat

<FONT COLOR="#800000">db.driver=org.hsqldb.jdbcDriver</FONT>
<FONT COLOR="#800000">db.url=jdbc:hsqldb:db/test</FONT>
<FONT COLOR="#800000">db.user=sa</FONT>
<FONT COLOR="#800000">db.pw=</FONT></PRE>
		</TD>
	</TR>
</TABLE>
<P STYLE="margin-bottom: 0in">Next I add the targets I need to the
build script. There are targets to create and delete tables and to
load and delete test data.
</P>
<TABLE WIDTH=807 BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0>
	<COL WIDTH=797>
	<TR>
		<TD WIDTH=797 VALIGN=TOP BGCOLOR="#ffffff">
			<PRE><FONT COLOR="#800000">    &lt;target name=&quot;createTables&quot;&gt;</FONT>
<FONT COLOR="#800000">        &lt;echo message=&quot;CREATE TABLES USING: ${db.driver} ${db.url}&quot;/&gt;</FONT>
<FONT COLOR="#800000">        &lt;sql driver=&quot;${db.driver}&quot;</FONT>
<FONT COLOR="#800000">             url=&quot;${db.url}&quot;</FONT>
<FONT COLOR="#800000">             userid=&quot;${db.user}&quot;</FONT>
<FONT COLOR="#800000">             password=&quot;${db.pw}&quot;</FONT>
<FONT COLOR="#800000">             onerror=&quot;continue&quot;&gt;  </FONT>
<FONT COLOR="#800000">            &lt;classpath refid=&quot;master-classpath&quot;/&gt;</FONT>

<FONT COLOR="#800000">        CREATE TABLE products (</FONT>
<FONT COLOR="#800000">          id INT(4) NOT NULL PRIMARY KEY,</FONT>
<FONT COLOR="#800000">          description varchar(255),</FONT>
<FONT COLOR="#800000">          price decimal(15,2)</FONT>
<FONT COLOR="#800000">        );</FONT>
<FONT COLOR="#800000">        CREATE INDEX products_description ON products(description);</FONT>

<FONT COLOR="#800000">        &lt;/sql&gt; </FONT>
<FONT COLOR="#800000">    &lt;/target&gt;</FONT>

<FONT COLOR="#800000">    &lt;target name=&quot;dropTables&quot;&gt;</FONT>
<FONT COLOR="#800000">        &lt;echo message=&quot;DROP TABLES USING: ${db.driver} ${db.url}&quot;/&gt;</FONT>
<FONT COLOR="#800000">        &lt;sql driver=&quot;${db.driver}&quot;</FONT>
<FONT COLOR="#800000">             url=&quot;${db.url}&quot;</FONT>
<FONT COLOR="#800000">             userid=&quot;${db.user}&quot;</FONT>
<FONT COLOR="#800000">             password=&quot;${db.pw}&quot;</FONT>
<FONT COLOR="#800000">             onerror=&quot;continue&quot;&gt;  </FONT>
<FONT COLOR="#800000">            &lt;classpath refid=&quot;master-classpath&quot;/&gt;</FONT>

<FONT COLOR="#800000">        DROP TABLE products;</FONT>

<FONT COLOR="#800000">        &lt;/sql&gt; </FONT>
<FONT COLOR="#800000">    &lt;/target&gt;</FONT>

<FONT COLOR="#800000">    &lt;target name=&quot;loadData&quot;&gt;</FONT>
<FONT COLOR="#800000">        &lt;echo message=&quot;LOAD DATA USING: ${db.driver} ${db.url}&quot;/&gt;</FONT>
<FONT COLOR="#800000">        &lt;sql driver=&quot;${db.driver}&quot;</FONT>
<FONT COLOR="#800000">             url=&quot;${db.url}&quot;</FONT>
<FONT COLOR="#800000">             userid=&quot;${db.user}&quot;</FONT>
<FONT COLOR="#800000">             password=&quot;${db.pw}&quot;</FONT>
<FONT COLOR="#800000">             onerror=&quot;continue&quot;&gt;  </FONT>
<FONT COLOR="#800000">            &lt;classpath refid=&quot;master-classpath&quot;/&gt;</FONT>

<FONT COLOR="#800000">        INSERT INTO products (id, description, price) values(1, 'Lamp', 5.78);</FONT>
<FONT COLOR="#800000">        INSERT INTO products (id, description, price) values(2, 'Table', 75.29);</FONT>
<FONT COLOR="#800000">        INSERT INTO products (id, description, price) values(3, 'Chair', 22.81);</FONT>

<FONT COLOR="#800000">        &lt;/sql&gt; </FONT>
<FONT COLOR="#800000">    &lt;/target&gt;</FONT>

<FONT COLOR="#800000">    &lt;target name=&quot;printData&quot;&gt;</FONT>
<FONT COLOR="#800000">        &lt;echo message=&quot;PRINT DATA USING: ${db.driver} ${db.url}&quot;/&gt;</FONT>
<FONT COLOR="#800000">        &lt;sql driver=&quot;${db.driver}&quot;</FONT>
<FONT COLOR="#800000">             url=&quot;${db.url}&quot;</FONT>
<FONT COLOR="#800000">             userid=&quot;${db.user}&quot;</FONT>
<FONT COLOR="#800000">             password=&quot;${db.pw}&quot;</FONT>
<FONT COLOR="#800000">             onerror=&quot;continue&quot;</FONT>
<FONT COLOR="#800000">             print=&quot;true&quot;&gt;  </FONT>
<FONT COLOR="#800000">            &lt;classpath refid=&quot;master-classpath&quot;/&gt;</FONT>

<FONT COLOR="#800000">        SELECT * FROM products;</FONT>

<FONT COLOR="#800000">        &lt;/sql&gt; </FONT>
<FONT COLOR="#800000">    &lt;/target&gt;</FONT>

<FONT COLOR="#800000">    &lt;target name=&quot;clearData&quot;&gt;</FONT>
<FONT COLOR="#800000">        &lt;echo message=&quot;CLEAR DATA USING: ${db.driver} ${db.url}&quot;/&gt;</FONT>
<FONT COLOR="#800000">        &lt;sql driver=&quot;${db.driver}&quot;</FONT>
<FONT COLOR="#800000">             url=&quot;${db.url}&quot;</FONT>
<FONT COLOR="#800000">             userid=&quot;${db.user}&quot;</FONT>
<FONT COLOR="#800000">             password=&quot;${db.pw}&quot;</FONT>
<FONT COLOR="#800000">             onerror=&quot;continue&quot;&gt;  </FONT>
<FONT COLOR="#800000">            &lt;classpath refid=&quot;master-classpath&quot;/&gt;</FONT>

<FONT COLOR="#800000">        DELETE FROM products;</FONT>

<FONT COLOR="#800000">        &lt;/sql&gt; </FONT>
<FONT COLOR="#800000">    &lt;/target&gt;</FONT></PRE>
		</TD>
	</TR>
</TABLE>
<P STYLE="margin-bottom: 0in">Now I execute some of these tasks to
set up the test database. This will create a db folder under the
springapp directory. Run 'ant createTables loadData printData' – I
have included my output below.</P>
<TABLE WIDTH=85% BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0>
	<COL WIDTH=256*>
	<TR>
		<TD WIDTH=100% VALIGN=TOP BGCOLOR="#e6e6ff">
			<PRE><FONT COLOR="#280099">[trisberg@localhost springapp]$ ant createTables loadData printData</FONT>
<FONT COLOR="#280099">Buildfile: build.xml</FONT>
<FONT COLOR="#280099"> </FONT>
<FONT COLOR="#280099">createTables:</FONT>
<FONT COLOR="#280099">     [echo] CREATE TABLES USING: org.hsqldb.jdbcDriver jdbc:hsqldb:db/test</FONT>
<FONT COLOR="#280099">      [sql] Executing commands</FONT>
<FONT COLOR="#280099">      [sql] 2 of 2 SQL statements executed successfully</FONT>
<FONT COLOR="#280099"> </FONT>
<FONT COLOR="#280099">loadData:</FONT>
<FONT COLOR="#280099">     [echo] LOAD DATA USING: org.hsqldb.jdbcDriver jdbc:hsqldb:db/test</FONT>
<FONT COLOR="#280099">      [sql] Executing commands</FONT>
<FONT COLOR="#280099">      [sql] 3 of 3 SQL statements executed successfully</FONT>
<FONT COLOR="#280099"> </FONT>
<FONT COLOR="#280099">printData:</FONT>
<FONT COLOR="#280099">     [echo] PRINT DATA USING: org.hsqldb.jdbcDriver jdbc:hsqldb:db/test</FONT>
<FONT COLOR="#280099">      [sql] Executing commands</FONT>
<FONT COLOR="#280099">      [sql] ID,DESCRIPTION,PRICE</FONT>
<FONT COLOR="#280099">      [sql] 1,Lamp,5.78</FONT>
<FONT COLOR="#280099">      [sql] 2,Table,75.29</FONT>
<FONT COLOR="#280099">      [sql] 3,Chair,22.81</FONT>
<FONT COLOR="#280099"> </FONT>
<FONT COLOR="#280099">      [sql] 1 of 1 SQL statements executed successfully</FONT>
<FONT COLOR="#280099"> </FONT>
<FONT COLOR="#280099">BUILD SUCCESSFUL</FONT>
<FONT COLOR="#280099">Total time: 2 seconds</FONT></PRE>
		</TD>
	</TR>
</TABLE>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><B>Step 24 – Create a Data Access
Object (DAO) implementation for JDBC.</B></P>
<P STYLE="margin-bottom: 0in">I begin with creating a new
'springapp/src/db' directory to contain any classes that are used for
database access. In this directory I create a new interface called
'ProductManagerDao.java'. This will be the interface that defines the
functionality that the DAO implementation classes will provide – we
could choose to have more than one implementation.
</P>
<TABLE WIDTH=90% BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0>
	<COL WIDTH=256*>
	<TR>
		<TD WIDTH=100% VALIGN=TOP BGCOLOR="#ffcc99">
			<P><B><FONT SIZE=2><FONT FACE="Nimbus Mono L">springapp/src/db/ProductManagerDao.java</FONT></FONT></B>
						</P>
		</TD>
	</TR>
	<TR>
		<TD WIDTH=100% VALIGN=TOP BGCOLOR="#ffffcc">
			<PRE><FONT COLOR="#000000">package db;</FONT>

<FONT COLOR="#000000">import bus.Product;</FONT>
<FONT COLOR="#000000">import java.util.List;</FONT>

<FONT COLOR="#000000">public interface ProductManagerDao {</FONT>

<FONT COLOR="#000000">    public List getProductList();</FONT>

<FONT COLOR="#000000">    public void increasePrice(Product prod, int pct);</FONT>

<FONT COLOR="#000000">}</FONT></PRE>
		</TD>
	</TR>
</TABLE>
<P STYLE="margin-bottom: 0in">I'll follow this with a class called
'ProductManagerDaoJdbc.java' that will be the JDBC implementation of
this interface. Spring provides a JDBC abstraction framework that we
will make use of. The biggest difference between using straight JDBC
and Spring's JDBC framework is that you don't have to worry about
opening and closing the connection or any statements. It is all
handled for you. Another advantage is that you won't have to catch
any exceptions, unless you want to. Spring wraps all SQLExceptions in
it's own unchecked exception hierarchy inheriting from
DataAccessException. If you want to you can catch this exception, but
since most database exceptions are impossible to recover from anyway,
you might as well just let the exception propagate up to a higher
level.</P>
<TABLE WIDTH=924 BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0>
	<COL WIDTH=914>
	<TR>
		<TD WIDTH=914 VALIGN=TOP BGCOLOR="#ffcc99">
			<P><B><FONT SIZE=2><FONT FACE="Nimbus Mono L">springapp/src/db/ProductManagerDaoJdbc.java</FONT></FONT></B>
						</P>
		</TD>
	</TR>
	<TR>
		<TD WIDTH=914 VALIGN=TOP BGCOLOR="#ffffcc">
			<PRE><FONT COLOR="#000000">package db;</FONT>

<FONT COLOR="#000000">import bus.Product;</FONT>
<FONT COLOR="#000000">import java.util.List;</FONT>
<FONT COLOR="#000000">import java.sql.ResultSet;</FONT>
<FONT COLOR="#000000">import java.sql.SQLException;</FONT>
<FONT COLOR="#000000">import java.sql.Types;</FONT>
<FONT COLOR="#000000">import javax.sql.DataSource;</FONT>
<FONT COLOR="#000000">import org.apache.commons.logging.Log;</FONT>
<FONT COLOR="#000000">import org.apache.commons.logging.LogFactory;</FONT>
<FONT COLOR="#000000">import org.springframework.jdbc.object.MappingSqlQuery;</FONT>
<FONT COLOR="#000000">import org.springframework.jdbc.object.SqlUpdate;</FONT>
<FONT COLOR="#000000">import org.springframework.jdbc.core.SqlParameter;</FONT>

<FONT COLOR="#000000">public class ProductManagerDaoJdbc implements ProductManagerDao {</FONT>

<FONT COLOR="#000000">    /** Logger for this class and subclasses */</FONT>
<FONT COLOR="#000000">    protected final Log logger = LogFactory.getLog(getClass());</FONT>

<FONT COLOR="#000000">    private DataSource ds;</FONT>

<FONT COLOR="#000000">    public List getProductList() {</FONT>
<FONT COLOR="#000000">        logger.info(&quot;Getting products!&quot;);</FONT>
<FONT COLOR="#000000">        ProductQuery pq = new ProductQuery(ds);</FONT>
<FONT COLOR="#000000">        return pq.execute();</FONT>
<FONT COLOR="#000000">    }</FONT>

<FONT COLOR="#000000">    public void increasePrice(Product prod, int pct) {</FONT>
<FONT COLOR="#000000">        logger.info(&quot;Increasing price by &quot; + pct + &quot;%&quot;);</FONT>
<FONT COLOR="#000000">        SqlUpdate su = </FONT>
<FONT COLOR="#000000">            new SqlUpdate(ds, &quot;update products set price = price * (100 + ?) / 100 where id = ?&quot;);</FONT>
<FONT COLOR="#000000">        su.declareParameter(new SqlParameter(&quot;increase&quot;, Types.INTEGER));</FONT>
<FONT COLOR="#000000">        su.declareParameter(new SqlParameter(&quot;ID&quot;, Types.INTEGER));</FONT>
<FONT COLOR="#000000">        su.compile();</FONT>
<FONT COLOR="#000000">        Object[] oa = new Object[2];</FONT>
<FONT COLOR="#000000">        oa[0] = new Integer(pct);</FONT>
<FONT COLOR="#000000">        oa[1] = new Integer(prod.getId());</FONT>
<FONT COLOR="#000000">        int count = su.update(oa);</FONT>
<FONT COLOR="#000000">        logger.info(&quot;Rows affected: &quot; + count);</FONT>
<FONT COLOR="#000000">    }</FONT>

<FONT COLOR="#000000">    public void setDataSource(DataSource ds) {</FONT>
<FONT COLOR="#000000">        this.ds = ds;</FONT>
<FONT COLOR="#000000">    }</FONT>

<FONT COLOR="#000000">    class ProductQuery extends MappingSqlQuery {</FONT>

<FONT COLOR="#000000">        ProductQuery(DataSource ds) {</FONT>
<FONT COLOR="#000000">            super(ds, &quot;SELECT id, description, price from products&quot;);</FONT>
<FONT COLOR="#000000">            compile();</FONT>
<FONT COLOR="#000000">        }</FONT>
<FONT COLOR="#000000"> </FONT>
<FONT COLOR="#000000">        protected Object mapRow(ResultSet rs, int rowNum) throws SQLException {</FONT>
<FONT COLOR="#000000">            Product prod = new Product();</FONT>
<FONT COLOR="#000000">            prod.setId(rs.getInt(&quot;id&quot;));</FONT>
<FONT COLOR="#000000">            prod.setDescription(rs.getString(&quot;description&quot;));</FONT>
<FONT COLOR="#000000">            prod.setPrice(new Double(rs.getDouble(&quot;price&quot;)));</FONT>
<FONT COLOR="#000000">            return prod;</FONT>
<FONT COLOR="#000000">        }</FONT>

<FONT COLOR="#000000">    }</FONT>

<FONT COLOR="#000000">}</FONT></PRE>
		</TD>
	</TR>
</TABLE>
<P STYLE="margin-bottom: 0in">Lets go over the two DAO methods in
this class. First, <FONT COLOR="#000000">getProductList()</FONT>
creates a query object that will retrieve all the products. This
query is executed and the results are passed back as a list of
Products. At the end of the class we can see the definition for this
query class. I have implemented it as an inner class since we are not
going to reference it anywhere else, but I could just as well have
made it a separate class. This query class extends MappingSqlQuery,
which is a central class in Spring's JDBC framework. The idea behind
this class is that you have to specify a SQL query when this class is
created, and you are also responsible for implementing the mapRow
method to map the data from each row into a class that represents the
entity you are retrieving in your query. That's it, that's all you
have to provide. The rest is managed by the framework. In the
constructor of the ProductQuery class I pass in the data source. This
data source will be provided in a similar fashion to the way we wired
up the business objects in Part 2, so we don't have to worry about
retrieving a data source in our DAO class. In the constructor I also
define the SQL query that we will use to retrieve the products. The
mapRow method will be called once for each row returned by the query.
It creates a new Product and populates it based on the data retrieved
from the current row of the resultset. You should not call getNext on
the resultset, it is all handled by the framework. This is another
example of an Inversion of Control solution.
</P>
<P STYLE="margin-bottom: 0in">The second method increasePrice is
utilizing an SqlUpdate class. This class is passed the data source
and an SQL update statement with placeholders for parameters. Same
syntax as a prepared statement in JDBC. In fact, that is what
SqlUpdate creates behind the scenes. For the parameters, we have to
give them a name and declare what type they are so that the framework
can set them before the prepared statement is executed. After all
parameters have been declared, we “compile�? the statement in JDO
fashion. This will signal that we are done declaring parameters, and
the framework will check to make sure that we have a matching
declaration for each placeholder in the SQL statement. Next we
declare an Object array that will hold the parameter values that we
are going to pass in to the prepared statement. This array gets
passed into the update method of SqlUpdate. The update method does
return the count of rows affected.</P>
<P STYLE="margin-bottom: 0in">I need to store the value of the
primary key for each product in the Product class. This key will be
used when I persist any changes to the object back to the database.
To hold this key I add a private field named 'id' complete with
setters and getters to Product.java.</P>
<TABLE WIDTH=90% BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0>
	<COL WIDTH=256*>
	<TR>
		<TD WIDTH=100% VALIGN=TOP BGCOLOR="#ffcc99">
			<P><B><FONT SIZE=2><FONT FACE="Nimbus Mono L">springapp/src/bus/Product.java</FONT></FONT></B>
						</P>
		</TD>
	</TR>
	<TR>
		<TD WIDTH=100% VALIGN=TOP BGCOLOR="#ffffcc">
			<PRE><FONT COLOR="#000000">package bus;</FONT>

<FONT COLOR="#000000">import java.io.Serializable;</FONT>

<FONT COLOR="#000000">public class Product implements Serializable {</FONT>

<FONT COLOR="#800000">    private int id;</FONT>
<FONT COLOR="#000000">    private String description;</FONT>
<FONT COLOR="#000000">    private Double price;</FONT>

<FONT COLOR="#800000">    public void setId(int i) {</FONT>
<FONT COLOR="#800000">        id = i;</FONT>
<FONT COLOR="#800000">    }</FONT>

<FONT COLOR="#800000">    public int getId() {</FONT>
<FONT COLOR="#800000">        return id;</FONT>
<FONT COLOR="#800000">    }</FONT>

<FONT COLOR="#000000">    public void setDescription(String s) {</FONT>
<FONT COLOR="#000000">        description = s;</FONT>
<FONT COLOR="#000000">    }</FONT>

<FONT COLOR="#000000">    public String getDescription() {</FONT>
<FONT COLOR="#000000">        return description;</FONT>
<FONT COLOR="#000000">    }</FONT>

<FONT COLOR="#000000">    public void setPrice(Double d) {</FONT>
<FONT COLOR="#000000">        price = d;</FONT>
<FONT COLOR="#000000">    }</FONT>

<FONT COLOR="#000000">    public Double getPrice() {</FONT>
<FONT COLOR="#000000">        return price;</FONT>
<FONT COLOR="#000000">    }</FONT>

<FONT COLOR="#000000">}</FONT></PRE>
		</TD>
	</TR>
</TABLE>
<P STYLE="margin-bottom: 0in">Now it is time to test this whole DAO
setup. Actually, we probably should have written the tests first, but
since this is a tutorial style document I think it makes more sense
to introduce the actual code before the tests. I decided to test with
a live database, so I will have to add dependencies for clearData and
loadData to the junit task in the build.xml. This will ensure that we
will have a consistent starting point for our tests.</P>
<TABLE WIDTH=849 BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0>
	<COL WIDTH=839>
	<TR>
		<TD WIDTH=839 VALIGN=TOP BGCOLOR="#ffffff">
			<PRE><FONT COLOR="#000000">    &lt;target name=&quot;junit&quot; depends=&quot;build<FONT COLOR="#800000">,clearData,loadData</FONT>&quot; description=&quot;Run JUnit Tests&quot;&gt;</FONT>
<FONT COLOR="#000000">        &lt;junit printsummary=&quot;on&quot;</FONT>
<FONT COLOR="#000000">               fork=&quot;false&quot;</FONT>
<FONT COLOR="#000000">               haltonfailure=&quot;false&quot;</FONT>
<FONT COLOR="#000000">               failureproperty=&quot;tests.failed&quot;</FONT>
<FONT COLOR="#000000">               showoutput=&quot;true&quot;&gt;</FONT>
<FONT COLOR="#000000">            &lt;classpath refid=&quot;master-classpath&quot;/&gt;</FONT>
<FONT COLOR="#000000">            &lt;formatter type=&quot;brief&quot; usefile=&quot;false&quot;/&gt;</FONT>

<FONT COLOR="#000000">            &lt;batchtest&gt;</FONT>
<FONT COLOR="#000000">                &lt;fileset dir=&quot;${build.dir}&quot;&gt;</FONT>
<FONT COLOR="#000000">                    &lt;include name=&quot;**/Test*.*&quot;/&gt;</FONT>
<FONT COLOR="#000000">                &lt;/fileset&gt;</FONT>
<FONT COLOR="#000000">            &lt;/batchtest&gt;</FONT>

<FONT COLOR="#000000">        &lt;/junit&gt;</FONT>

<FONT COLOR="#000000">        &lt;fail if=&quot;tests.failed&quot;&gt;</FONT>
<FONT COLOR="#000000">        ***********************************************************</FONT>
<FONT COLOR="#000000">        ***********************************************************</FONT>
<FONT COLOR="#000000">        ****  One or more tests failed!  Check the output ...  ****</FONT>
<FONT COLOR="#000000">        ***********************************************************</FONT>
<FONT COLOR="#000000">        ***********************************************************</FONT>
<FONT COLOR="#000000">        &lt;/fail&gt;</FONT>
<FONT COLOR="#000000">    &lt;/target&gt;</FONT></PRE>
		</TD>
	</TR>
</TABLE>
<P STYLE="margin-bottom: 0in">Next, I add a
TestProductManagerDaoJdbc.java to our collection of unit tests. In
the setup part I create a data source that will be used for testing.
</P>
<TABLE WIDTH=90% BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0>
	<COL WIDTH=256*>
	<TR>
		<TD WIDTH=100% VALIGN=TOP BGCOLOR="#ffcc99">
			<P><B><FONT SIZE=2><FONT FACE="Nimbus Mono L">springapp/src/test/TestProductManagerDaoJdbc.java</FONT></FONT></B>
						</P>
		</TD>
	</TR>
	<TR>
		<TD WIDTH=100% VALIGN=TOP BGCOLOR="#ffffcc">
			<PRE><FONT COLOR="#000000">package tests;</FONT>

<FONT COLOR="#000000">import java.util.List;</FONT>
<FONT COLOR="#000000">import java.util.ArrayList;</FONT>
<FONT COLOR="#000000">import junit.framework.TestCase;</FONT>
<FONT COLOR="#000000">import org.springframework.jdbc.datasource.DriverManagerDataSource;</FONT>
<FONT COLOR="#000000">import db.ProductManagerDaoJdbc;</FONT>
<FONT COLOR="#000000">import bus.Product;</FONT>

<FONT COLOR="#000000">public class TestProductManagerDaoJdbc extends TestCase {</FONT>

<FONT COLOR="#000000">    private ProductManagerDaoJdbc pmdao;</FONT>

<FONT COLOR="#000000">    public void setUp() {</FONT>
<FONT COLOR="#000000">        pmdao = new ProductManagerDaoJdbc();</FONT>
<FONT COLOR="#000000">        DriverManagerDataSource ds = new DriverManagerDataSource();</FONT>
<FONT COLOR="#000000">        ds.setDriverClassName(&quot;org.hsqldb.jdbcDriver&quot;);</FONT>
<FONT COLOR="#000000">        ds.setUrl(&quot;jdbc:hsqldb:db/test&quot;);</FONT>
<FONT COLOR="#000000">        ds.setUsername(&quot;sa&quot;);</FONT>
<FONT COLOR="#000000">        ds.setPassword(&quot;&quot;);</FONT>
<FONT COLOR="#000000">        pmdao.setDataSource(ds);</FONT>
<FONT COLOR="#000000">    }</FONT>

<FONT COLOR="#000000">    public void testGetProductList() {</FONT>
<FONT COLOR="#000000">        List l = pmdao.getProductList();</FONT>
<FONT COLOR="#000000">        Product p1 = (Product) l.get(0);</FONT>
<FONT COLOR="#000000">        assertEquals(&quot;Lamp&quot;, p1.getDescription());</FONT>
<FONT COLOR="#000000">        Product p2 = (Product) l.get(1);</FONT>
<FONT COLOR="#000000">        assertEquals(&quot;Table&quot;, p2.getDescription());</FONT>
<FONT COLOR="#000000">    }</FONT>

<FONT COLOR="#000000">    public void testIncreasePrice() {</FONT>
<FONT COLOR="#000000">        List l1 = pmdao.getProductList();</FONT>
<FONT COLOR="#000000">        Product p1 = (Product) l1.get(0);</FONT>
<FONT COLOR="#000000">        assertEquals(new Double(&quot;5.78&quot;), p1.getPrice());</FONT>
<FONT COLOR="#000000">        pmdao.increasePrice(p1, 10);</FONT>
<FONT COLOR="#000000">        List l2 = pmdao.getProductList();</FONT>
<FONT COLOR="#000000">        Product p2 = (Product) l2.get(0);</FONT>
<FONT COLOR="#000000">        assertEquals(new Double(&quot;6.36&quot;), p2.getPrice());</FONT>
<FONT COLOR="#000000">    }</FONT>

<FONT COLOR="#000000">}</FONT></PRE>
		</TD>
	</TR>
</TABLE>
<P STYLE="margin-bottom: 0in">When we pass the unit tests, we can
move on and modify the web application to make use of these new
database persistence capabilities.</P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><B>Step 25 – Modify web application
to use database persistence.</B></P>
<P STYLE="margin-bottom: 0in">If we structured our application
properly, we should only have to change the business classes to take
advantage of the database persistence. The view and controller
classes should not have to be modified, since they should be unaware
of any implementation details of the business classes. So let's add
the persistence to the ProductManager class. I add a reference to a
ProductManagerDao interface plus a setter method for this reference.
Which implementation that we actually use should be irrelevant to the
ProductManager class, and we will set this through a configuration
option.</P>
<TABLE WIDTH=907 BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0>
	<COL WIDTH=897>
	<TR>
		<TD WIDTH=897 VALIGN=TOP BGCOLOR="#ffcc99">
			<P><FONT FACE="Nimbus Mono L"><FONT SIZE=2><B>springapp/src/bus/ProductManager.java</B></FONT></FONT></P>
		</TD>
	</TR>
	<TR>
		<TD WIDTH=897 VALIGN=TOP BGCOLOR="#ffffcc">
			<PRE><FONT COLOR="#000000">package bus;</FONT>

<FONT COLOR="#000000">import java.io.Serializable;</FONT>
<FONT COLOR="#000000">import java.util.ListIterator;</FONT>
<FONT COLOR="#000000">import java.util.List;</FONT>
<FONT COLOR="#800000">import db.ProductManagerDao;</FONT>

<FONT COLOR="#000000">public class ProductManager implements Serializable {</FONT>

<FONT COLOR="#800000">    private ProductManagerDao pmd;</FONT>
<FONT COLOR="#000000">    private List products;</FONT>

<FONT COLOR="#800000">    public void setProductManagerDao(ProductManagerDao pmd) {</FONT>
<FONT COLOR="#800000">        this.pmd = pmd;</FONT>
<FONT COLOR="#800000">    }</FONT>

<FONT COLOR="#808080">/*  </FONT>
<FONT COLOR="#808080">    public void setProducts(List p) {</FONT>
<FONT COLOR="#808080">        products = p;</FONT>
<FONT COLOR="#808080">    }</FONT>
<FONT COLOR="#808080">*/</FONT>

<FONT COLOR="#000000">    public List getProducts() {</FONT>
<FONT COLOR="#800000">        products = pmd.getProductList();</FONT>
<FONT COLOR="#000000">        return products;</FONT>
<FONT COLOR="#000000">    }</FONT>

<FONT COLOR="#000000">    public void increasePrice(int pct) {</FONT>
<FONT COLOR="#000000">        ListIterator li = products.listIterator();</FONT>
<FONT COLOR="#000000">        while (li.hasNext()) {</FONT>
<FONT COLOR="#000000">            Product p = (Product) li.next();</FONT>
<FONT COLOR="#808080">/*</FONT>
<FONT COLOR="#808080">            double newPrice = p.getPrice().doubleValue() * (100 + pct)/100;</FONT>
<FONT COLOR="#808080">            p.setPrice(new Double(newPrice));</FONT>
<FONT COLOR="#808080">*/</FONT>
<FONT COLOR="#800000">            pmd.increasePrice(p, pct);</FONT>
<FONT COLOR="#000000">        }</FONT>
<FONT COLOR="#000000">        </FONT>
<FONT COLOR="#000000">    }</FONT>

<FONT COLOR="#000000">}</FONT></PRE>
		</TD>
	</TR>
</TABLE>
<P STYLE="margin-bottom: 0in">We will no longer rely on the product
list that we have in memory. Every time getProducts is called, we
will go out and query the database. The increasePrice method will now
delegate to the DAO to increase the price and the new price will be
reflected the next time we call the getProducts method.</P>
<P STYLE="margin-bottom: 0in">Next we need to modify the
configuration file for the web application – springapp-servlet.xml.</P>
<TABLE WIDTH=955 BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0>
	<COL WIDTH=945>
	<TR>
		<TD WIDTH=945 VALIGN=TOP BGCOLOR="#ffcc99">
			<P><B><FONT SIZE=2><FONT FACE="Nimbus Mono L">springapp/war/WEB-INF/springapp-servlet.xml</FONT></FONT></B>
						</P>
		</TD>
	</TR>
	<TR>
		<TD WIDTH=945 VALIGN=TOP BGCOLOR="#ffffcc">
			<PRE>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE beans PUBLIC &quot;-//SPRING//DTD BEAN//EN&quot;
 &quot;http://www.springframework.org/dtd/spring-beans.dtd&quot;&gt;

<FONT COLOR="#000000">&lt;!--</FONT>
<FONT COLOR="#000000">  - Application context definition for &quot;springapp&quot; DispatcherServlet.</FONT>
<FONT COLOR="#000000">  --&gt;</FONT>

<FONT COLOR="#000000">&lt;beans&gt;</FONT>

<FONT COLOR="#000000">    &lt;!--  Controller for the initial &quot;Hello&quot; page --&gt;</FONT>
<FONT COLOR="#000000">    &lt;bean id=&quot;springappController&quot; class=&quot;web.SpringappController&quot;&gt;</FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;productManager&quot;&gt;</FONT>
<FONT COLOR="#000000">            &lt;ref bean=&quot;prodMan&quot;/&gt;</FONT>
<FONT COLOR="#000000">        &lt;/property&gt;</FONT>
<FONT COLOR="#000000">    &lt;/bean&gt;</FONT>

<FONT COLOR="#000000">    &lt;!--  Validator and Form Controller for the &quot;Price Increase&quot; page --&gt;</FONT>
<FONT COLOR="#000000">    &lt;bean id=&quot;priceIncreaseValidator&quot; class=&quot;bus.PriceIncreaseValidator&quot;/&gt;</FONT>
<FONT COLOR="#000000">    &lt;bean id=&quot;priceIncreaseForm&quot; class=&quot;web.PriceIncreaseFormController&quot;&gt;</FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;sessionForm&quot;&gt;&lt;value&gt;true&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;beanName&quot;&gt;&lt;value&gt;priceIncrease&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;commandClass&quot;&gt;&lt;value&gt;bus.PriceIncrease&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;validator&quot;&gt;&lt;ref bean=&quot;priceIncreaseValidator&quot;/&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;formView&quot;&gt;&lt;value&gt;priceincrease&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;successView&quot;&gt;&lt;value&gt;hello.htm&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;productManager&quot;&gt;</FONT>
<FONT COLOR="#000000">            &lt;ref bean=&quot;prodMan&quot;/&gt;</FONT>
<FONT COLOR="#000000">        &lt;/property&gt;</FONT>
<FONT COLOR="#000000">    &lt;/bean&gt;</FONT>

<FONT COLOR="#800000">    &lt;bean id=&quot;dataSource&quot; class=&quot;org.springframework.jdbc.datasource.DriverManagerDataSource&quot;&gt;</FONT>
<FONT COLOR="#800000">      &lt;property name=&quot;driverClassName&quot;&gt;&lt;value&gt;org.hsqldb.jdbcDriver&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#800000">      &lt;property name=&quot;url&quot;&gt;</FONT>
<FONT COLOR="#800000">        &lt;value&gt;jdbc:hsqldb:/home/trisberg/workspace/springapp/db/test&lt;/value&gt;</FONT>
<FONT COLOR="#800000">      &lt;/property&gt;</FONT>
<FONT COLOR="#800000">      &lt;property name=&quot;username&quot;&gt;&lt;value&gt;sa&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#800000">      &lt;property name=&quot;password&quot;&gt;&lt;value&gt;&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#800000">    &lt;/bean&gt;</FONT>

<FONT COLOR="#800000">    &lt;bean id=&quot;prodManDao&quot; class=&quot;db.ProductManagerDaoJdbc&quot;&gt;</FONT>
<FONT COLOR="#800000">        &lt;property name=&quot;dataSource&quot;&gt;</FONT>
<FONT COLOR="#800000">            &lt;ref bean=&quot;dataSource&quot;/&gt;</FONT>
<FONT COLOR="#800000">        &lt;/property&gt;</FONT>
<FONT COLOR="#800000">    &lt;/bean&gt;</FONT>

    &lt;bean id=&quot;prodMan&quot; class=&quot;bus.ProductManager&quot;&gt;
<FONT COLOR="#800000">        &lt;property name=&quot;productManagerDao&quot;&gt;</FONT>
<FONT COLOR="#800000">            &lt;ref bean=&quot;prodManDao&quot;/&gt;</FONT>
<FONT COLOR="#800000">        &lt;/property&gt;</FONT>
<FONT COLOR="#808080">&lt;!--</FONT>
<FONT COLOR="#808080">        &lt;property name=&quot;products&quot;&gt;</FONT>
<FONT COLOR="#808080">            &lt;list&gt;</FONT>
<FONT COLOR="#808080">                &lt;ref bean=&quot;product1&quot;/&gt;</FONT>
<FONT COLOR="#808080">                &lt;ref bean=&quot;product2&quot;/&gt;</FONT>
<FONT COLOR="#808080">                &lt;ref bean=&quot;product3&quot;/&gt;</FONT>
<FONT COLOR="#808080">            &lt;/list&gt;</FONT>
<FONT COLOR="#808080">        &lt;/property&gt;</FONT>
<FONT COLOR="#808080">--&gt;</FONT>
<FONT COLOR="#000000">    &lt;/bean&gt;</FONT>
<FONT COLOR="#800000">    </FONT>
<FONT COLOR="#808080">&lt;!--</FONT>
<FONT COLOR="#808080"><SPAN STYLE="text-decoration: none">    </SPAN>&lt;bean id=&quot;product1&quot; class=&quot;bus.Product&quot;&gt;</FONT>
<FONT COLOR="#808080"><SPAN STYLE="text-decoration: none">        </SPAN>&lt;property name=&quot;description&quot;&gt;&lt;value&gt;Lamp&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#808080"><SPAN STYLE="text-decoration: none">        </SPAN>&lt;property name=&quot;price&quot;&gt;&lt;value&gt;5.75&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#808080"><SPAN STYLE="text-decoration: none">    </SPAN>&lt;/bean&gt;</FONT>
<FONT COLOR="#808080">        </FONT>
<FONT COLOR="#808080"><SPAN STYLE="text-decoration: none">    </SPAN>&lt;bean id=&quot;product2&quot; class=&quot;bus.Product&quot;&gt;</FONT>
<FONT COLOR="#808080"><SPAN STYLE="text-decoration: none">        </SPAN>&lt;property name=&quot;description&quot;&gt;&lt;value&gt;Table&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#808080"><SPAN STYLE="text-decoration: none">        </SPAN>&lt;property name=&quot;price&quot;&gt;&lt;value&gt;75.25&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#808080"><SPAN STYLE="text-decoration: none">    </SPAN>&lt;/bean&gt;</FONT>

<FONT COLOR="#808080"><SPAN STYLE="text-decoration: none">    </SPAN>&lt;bean id=&quot;product3&quot; class=&quot;bus.Product&quot;&gt;</FONT>
<FONT COLOR="#808080"><SPAN STYLE="text-decoration: none">        </SPAN>&lt;property name=&quot;description&quot;&gt;&lt;value&gt;Chair&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#808080"><SPAN STYLE="text-decoration: none">        </SPAN>&lt;property name=&quot;price&quot;&gt;&lt;value&gt;22.79&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#808080"><SPAN STYLE="text-decoration: none">    </SPAN>&lt;/bean&gt;</FONT>
<FONT COLOR="#808080">--&gt;</FONT>

<FONT COLOR="#000000">    &lt;bean id=&quot;messageSource&quot; class=&quot;org.springframework.context.support.ResourceBundleMessageSource&quot;&gt;</FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;basename&quot;&gt;&lt;value&gt;messages&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#000000">    &lt;/bean&gt;</FONT>

<FONT COLOR="#000000">    &lt;bean id=&quot;urlMapping&quot; class=&quot;org.springframework.web.servlet.handler.SimpleUrlHandlerMapping&quot;&gt; </FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;mappings&quot;&gt;</FONT>
<FONT COLOR="#000000">            &lt;props&gt;</FONT>
<FONT COLOR="#000000">                &lt;prop key=&quot;/hello.htm&quot;&gt;springappController&lt;/prop&gt;</FONT>
<FONT COLOR="#000000">                &lt;prop key=&quot;/priceincrease.htm&quot;&gt;priceIncreaseForm&lt;/prop&gt;</FONT>
<FONT COLOR="#000000">            &lt;/props&gt;</FONT>
<FONT COLOR="#000000">        &lt;/property&gt;</FONT>
<FONT COLOR="#000000">    &lt;/bean&gt;</FONT>

<FONT COLOR="#000000">    &lt;bean id=&quot;viewResolver&quot; class=&quot;org.springframework.web.servlet.view.InternalResourceViewResolver&quot;&gt;</FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;viewClass&quot;&gt;</FONT>
<FONT COLOR="#000000">           &lt;value&gt;org.springframework.web.servlet.view.JstlView&lt;/value&gt;</FONT>
<FONT COLOR="#000000">        &lt;/property&gt;</FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;prefix&quot;&gt;&lt;value&gt;/WEB-INF/jsp/&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;suffix&quot;&gt;&lt;value&gt;.jsp&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#000000">    &lt;/bean&gt;</FONT>
&lt;/beans&gt;</PRE>
		</TD>
	</TR>
</TABLE>
<P STYLE="margin-bottom: 0in">I remove the population of a set of
products that were passed in to the ProductManager. I replace this by
adding beans for a DataSource and a ProductManagerDaoJdbc
implementation. The URL provided for the datasource includes the full
path for the database location
(/home/trisberg/workspace/springapp/db/test). You will of course have
to adjust this to match your setup.
</P>
<P STYLE="margin-bottom: 0in">Now we can build and deploy the
modified application. Run 'ant undeploy deploy' to clean out any of
the old classes and replace them with the new ones. Then fire up
Tomcat and pull up the application. The only difference you should
see is the decimals limited to two positions due to the column being
declared that way in the database. Also, you should see any price
increases remaining in effect even after you cycle the application
server.</P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><B>Step 26 – Fix the broken tests.</B></P>
<P STYLE="margin-bottom: 0in">We have radically changed the
ProductManager implementation – we pushed all the functionality
down to the ProductManagerDao implementation, so now the old tests
fail. To fix this I will create a mock implementation of the
ProductManagerDao. This implementation will basically mimic the
functionality we had in the original ProductManager.</P>
<TABLE WIDTH=907 BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0>
	<COL WIDTH=897>
	<TR>
		<TD WIDTH=897 VALIGN=TOP BGCOLOR="#ffcc99">
			<P><FONT FACE="Nimbus Mono L"><FONT SIZE=2><B>springapp/src/tests/MockProductManagerDaoImpl.java</B></FONT></FONT></P>
		</TD>
	</TR>
	<TR>
		<TD WIDTH=897 VALIGN=TOP BGCOLOR="#ffffcc">
			<PRE><FONT COLOR="#000000">package tests;</FONT>

<FONT COLOR="#000000">import bus.Product;</FONT>
<FONT COLOR="#000000">import java.util.List;</FONT>
<FONT COLOR="#000000">import db.ProductManagerDao;</FONT>
<FONT COLOR="#000000">import bus.Product;</FONT>

<FONT COLOR="#000000">public class MockProductManagerDaoImpl implements ProductManagerDao {</FONT>

<FONT COLOR="#000000">    private List products;</FONT>

<FONT COLOR="#000000">    public void setProducts(List p) {</FONT>
<FONT COLOR="#000000">        products = p;</FONT>
<FONT COLOR="#000000">    }</FONT>

<FONT COLOR="#000000">    public List getProductList() {</FONT>
<FONT COLOR="#000000">        return products;</FONT>
<FONT COLOR="#000000">    }</FONT>

<FONT COLOR="#000000">    public void increasePrice(Product prod, int pct) {</FONT>
<FONT COLOR="#000000">        double newPrice = prod.getPrice().doubleValue() * (100 + pct)/100;</FONT>
<FONT COLOR="#000000">        prod.setPrice(new Double(newPrice));</FONT>
<FONT COLOR="#000000">    }</FONT>

<FONT COLOR="#000000">}</FONT></PRE>
		</TD>
	</TR>
</TABLE>
<P STYLE="margin-bottom: 0in">Now we have to make sure to configure
the 'TestSpringappController' and 'TestProductManager' tests to use
this mock implementation. For the 'TestSpringappController' I will
modify the 'springapp-servlet.xml' file that I copied into the
tests/WEB-INF directory (I knew it would be a good idea to make a
copy of this file). Do not modify the one located in war/WEB-INF –
we need that one to stay as is so we can run the application in
Tomcat. We move the list of products from the ProductManager to the
ProductManagerDao and give ProductManager a reference to this DAO.</P>
<TABLE WIDTH=966 BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0>
	<COL WIDTH=956>
	<TR>
		<TD WIDTH=956 VALIGN=TOP BGCOLOR="#ffcc99">
			<P><B><FONT SIZE=2><FONT FACE="Nimbus Mono L">springapp/src/tests/WEB-INF/springapp-servlet.xml</FONT></FONT></B>
						</P>
		</TD>
	</TR>
	<TR>
		<TD WIDTH=956 VALIGN=TOP BGCOLOR="#ffffcc">
			<PRE><FONT COLOR="#000000">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;</FONT>
<FONT COLOR="#000000">&lt;!DOCTYPE beans PUBLIC &quot;-//SPRING//DTD BEAN//EN&quot; &quot;http://www.springframework.org/dtd/spring-beans.dtd&quot;&gt;</FONT>

<FONT COLOR="#000000">&lt;!--</FONT>
<FONT COLOR="#000000">  - Application context definition for &quot;springapp&quot; DispatcherServlet.</FONT>
<FONT COLOR="#000000">  --&gt;</FONT>


<FONT COLOR="#000000">&lt;beans&gt;</FONT>
<FONT COLOR="#000000">    &lt;bean id=&quot;springappController&quot; class=&quot;web.SpringappController&quot;&gt;</FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;productManager&quot;&gt;</FONT>
<FONT COLOR="#000000">            &lt;ref bean=&quot;prodMan&quot;/&gt;</FONT>
<FONT COLOR="#000000">        &lt;/property&gt;</FONT>
<FONT COLOR="#000000">    &lt;/bean&gt;</FONT>

<FONT COLOR="#800000">    &lt;bean id=&quot;prodManDao&quot; class=&quot;tests.MockProductManagerDaoImpl&quot;&gt;</FONT>
<FONT COLOR="#800000">        &lt;property name=&quot;products&quot;&gt;</FONT>
<FONT COLOR="#800000">            &lt;list&gt;</FONT>
<FONT COLOR="#800000">                &lt;ref bean=&quot;product1&quot;/&gt;</FONT>
<FONT COLOR="#800000">                &lt;ref bean=&quot;product2&quot;/&gt;</FONT>
<FONT COLOR="#800000">                &lt;ref bean=&quot;product3&quot;/&gt;</FONT>
<FONT COLOR="#800000">            &lt;/list&gt;</FONT>
<FONT COLOR="#800000">        &lt;/property&gt;</FONT>
<FONT COLOR="#800000">    &lt;/bean&gt;</FONT>

<FONT COLOR="#000000">    &lt;bean id=&quot;prodMan&quot; class=&quot;bus.ProductManager&quot;&gt;</FONT>
<FONT COLOR="#800000">        &lt;property name=&quot;productManagerDao&quot;&gt;</FONT>
<FONT COLOR="#800000">            &lt;ref bean=&quot;prodManDao&quot;/&gt;</FONT>
<FONT COLOR="#800000">        &lt;/property&gt;</FONT>
<FONT COLOR="#808080">&lt;!--</FONT>
<FONT COLOR="#808080">        &lt;property name=&quot;products&quot;&gt;</FONT>
<FONT COLOR="#808080">            &lt;list&gt;</FONT>
<FONT COLOR="#808080">                &lt;ref bean=&quot;product1&quot;/&gt;</FONT>
<FONT COLOR="#808080">                &lt;ref bean=&quot;product2&quot;/&gt;</FONT>
<FONT COLOR="#808080">                &lt;ref bean=&quot;product3&quot;/&gt;</FONT>
<FONT COLOR="#808080">            &lt;/list&gt;</FONT>
<FONT COLOR="#808080">        &lt;/property&gt;</FONT>
<FONT COLOR="#808080">--&gt;</FONT>
<FONT COLOR="#000000">    &lt;/bean&gt;</FONT>

<FONT COLOR="#000000">    &lt;bean id=&quot;product1&quot; class=&quot;bus.Product&quot;&gt;</FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;description&quot;&gt;&lt;value&gt;Lamp&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;price&quot;&gt;&lt;value&gt;5.75&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#000000">    &lt;/bean&gt;</FONT>
<FONT COLOR="#000000">        </FONT>
<FONT COLOR="#000000">    &lt;bean id=&quot;product2&quot; class=&quot;bus.Product&quot;&gt;</FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;description&quot;&gt;&lt;value&gt;Table&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;price&quot;&gt;&lt;value&gt;75.25&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#000000">    &lt;/bean&gt;</FONT>

<FONT COLOR="#000000">    &lt;bean id=&quot;product3&quot; class=&quot;bus.Product&quot;&gt;</FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;description&quot;&gt;&lt;value&gt;Chair&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#000000">        &lt;property name=&quot;price&quot;&gt;&lt;value&gt;22.79&lt;/value&gt;&lt;/property&gt;</FONT>
<FONT COLOR="#000000">    &lt;/bean&gt;</FONT>

<FONT COLOR="#000000">&lt;/beans&gt; </FONT>       </PRE>
		</TD>
	</TR>
</TABLE>
<P STYLE="margin-bottom: 0in">For the TestProductManager test case we
will make similar modifications to the setUp method.</P>
<TABLE WIDTH=908 BORDER=1 BORDERCOLOR="#000000" CELLPADDING=4 CELLSPACING=0>
	<COL WIDTH=898>
	<TR>
		<TD WIDTH=898 VALIGN=TOP BGCOLOR="#ffcc99">
			<P><B><FONT SIZE=2><FONT FACE="Nimbus Mono L">springapp/src/tests/TestProductManager
			.java</FONT></FONT></B>
			</P>
		</TD>
	</TR>
	<TR>
		<TD WIDTH=898 VALIGN=TOP BGCOLOR="#ffffcc">
			<PRE>package tests;

import java.util.List;
import java.util.ArrayList;
import junit.framework.TestCase;
<FONT COLOR="#800000">import db.ProductManagerDao;</FONT>
import bus.ProductManager;
import bus.Product;

public class TestProductManager extends TestCase {

    private ProductManager pm;

    public void setUp() {
        pm = new ProductManager();
        Product p = new Product();
        p.setDescription(&quot;Chair&quot;);
        p.setPrice(new Double(&quot;20.50&quot;));
        ArrayList al = new ArrayList();
        al.add(p);
        p = new Product();
        p.setDescription(&quot;Table&quot;);
        p.setPrice(new Double(&quot;150.10&quot;));
        al.add(p);
<FONT COLOR="#808080">/*</FONT>
<FONT COLOR="#808080">        pm.setProducts(al);</FONT>
<FONT COLOR="#808080">*/</FONT>
<FONT COLOR="#800000">        MockProductManagerDaoImpl pmdao = new MockProductManagerDaoImpl();</FONT>
<FONT COLOR="#800000">        pmdao.setProducts(al);</FONT>
<FONT COLOR="#800000">        pm.setProductManagerDao(pmdao);</FONT>
<FONT COLOR="#800000">        pm.getProducts();</FONT>
    }

    public void testGetProducs() {
        List l = pm.getProducts();
        Product p1 = (Product) l.get(0);
        assertEquals(&quot;Chair&quot;, p1.getDescription());
        Product p2 = (Product) l.get(1);
        assertEquals(&quot;Table&quot;, p2.getDescription());
    }

    public void testIncreasePrice() {
        pm.increasePrice(10);
        List l = pm.getProducts();
        Product p = (Product) l.get(0);
        assertEquals(new Double(&quot;22.55&quot;), p.getPrice());
        p = (Product) l.get(1);
        assertEquals(new Double(&quot;165.11&quot;), p.getPrice());
    }

}</PRE>
		</TD>
	</TR>
</TABLE>
<P STYLE="margin-bottom: 0in">Compile everything and run the tests.
They should run successfully now.</P>
<P STYLE="margin-bottom: 0in">There are still a few things I would
like to improve upon. To begin with, we are not using a connection
pool which is a must for any serious web application deployment. We
are also using HSQL in a standalone mode, which is limiting us to one
connection at a time. This of course will not scale. Another issue
that we are not dealing with is concurrency. Two users could increase
prices simultaneously and they would be a bit surprised by seeing the
combined effect of their actions. I'll leave these improvements up to
you for now – I might add them in an additional part to this
document in the future.</P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in"><A HREF="Spring-MVC-step-by-step.html" TARGET="_self">Back</A>
</P>
<P STYLE="margin-bottom: 0in"><BR>
</P>
<P STYLE="margin-bottom: 0in">Copyright &copy; 2003, Thomas Risberg</P>
</BODY>
</HTML>